﻿using System;
using System.Collections.Generic;
using System.IO;
using System.ServiceModel.Syndication;
using System.ServiceModel.Web;
using System.Net;
using System.Web;
using System.Xml;
using ScottLane.MediaFeeder.ObjectModel;

namespace ScottLane.MediaFeeder.WebService
{
    /// <summary>
    /// Partial class of MediaService that implements the Playlist related methods.
    /// </summary>
    public partial class MediaService : IMediaService
    {
        /// <summary>
        /// Gets a feed containing the playlist details.
        /// </summary>
        /// <param name="name">The playlist name.</param>
        /// <returns>The playlist feed.</returns>
        public SyndicationFeedFormatter GetPlaylist(string name)
        {
            string decodedName = HttpUtility.UrlDecode(name);

            if (!Playlist.Exists(decodedName))
            {
                WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.NotFound;
                return null;
            }

            Playlist playlist = new Playlist(decodedName);
            SyndicationFeed feed = new SyndicationFeed();
            feed.Title = new TextSyndicationContent(playlist.Name);
            feed.Description = new TextSyndicationContent(playlist.Name);
            feed.Links.Add(SyndicationLink.CreateAlternateLink(new Uri("http://code.google.com/p/mediafeeder/wiki/Playlist")));
            feed.Generator = XmlString.Generator;
            feed.AttributeExtensions.Add(new XmlQualifiedName(XmlString.ITunesLocalName, XmlString.GenericNameSpace), XmlString.ITunesNamespace);
            feed.AttributeExtensions.Add(new XmlQualifiedName(XmlString.MediaFeederLocalName, XmlString.GenericNameSpace), XmlString.MediaFeederNamespace);
            List<SyndicationItem> items = new List<SyndicationItem>();
            PlaylistSyndicationItem item = new PlaylistSyndicationItem(playlist);
            items.Add(item);
            feed.Items = items;
            return Utility.GetFormatter(feed);
        }

        /// <summary>
        /// Gets a feed of songs in the specified playlist.
        /// </summary>
        /// <param name="name">The playlist name.</param>
        /// <param name="startIndex"></param>
        /// <param name="maxResults"></param>
        /// <returns>The song feed.</returns>
        public SyndicationFeedFormatter GetPlaylistSongs(string name, string startIndex, string maxResults)
        {
            string decodedName = HttpUtility.UrlDecode(name);

            if (!Playlist.Exists(decodedName))
            {
                WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.NotFound;
                return null;
            }

            Playlist playlist = new Playlist(decodedName);
            SyndicationFeed feed = new SyndicationFeed();
            feed.Title = new TextSyndicationContent(playlist.Name + " Songs");
            feed.Description = new TextSyndicationContent("Songs in the playlist '" + playlist.Name + "'");
            feed.Links.Add(SyndicationLink.CreateAlternateLink(new Uri("http://code.google.com/p/mediafeeder/wiki/PlaylistSongs")));
            feed.Generator = XmlString.Generator;
            feed.AttributeExtensions.Add(new XmlQualifiedName(XmlString.ITunesLocalName, XmlString.GenericNameSpace), XmlString.ITunesNamespace);
            feed.AttributeExtensions.Add(new XmlQualifiedName(XmlString.MediaFeederLocalName, XmlString.GenericNameSpace), XmlString.MediaFeederNamespace);
            List<SyndicationItem> items = new List<SyndicationItem>();

            int parsedStartIndex = 0;
            int.TryParse(startIndex, out parsedStartIndex);

            int parsedMaxResults = 0;
            int.TryParse(maxResults, out parsedMaxResults);

            int finishIndex = playlist.Songs.Count - 1;

            if (parsedMaxResults > 0)
            {
                finishIndex = parsedStartIndex + parsedMaxResults;

                if (finishIndex > playlist.Songs.Count - 1)
                {
                    finishIndex = playlist.Songs.Count - 1;
                }
            }

            for (int index = parsedStartIndex; index <= finishIndex; index++)
            {
                Song song = playlist.Songs[index];

                if (song.Title != null)
                {
                    SongSyndicationItem item = new SongSyndicationItem(song);
                    items.Add(item);
                }
            }

            feed.Items = items;
            return Utility.GetFormatter(feed);
        }

        /// <summary>
        /// Gets a feed of playlists containing the specified name.
        /// </summary>
        /// <param name="name">The playlist name.</param>
        /// <param name="type">The playlist type.</param>
        /// <returns>The playlist feed.</returns>
        public SyndicationFeedFormatter GetPlaylists(string name, string type)
        {
            string decodedName = name;

            if (name != null)
            {
                decodedName = HttpUtility.UrlDecode(name);
            }

            PlaylistType parsedType = PlaylistType.Auto;

            if (type != null)
            {
                parsedType = (PlaylistType)Enum.Parse(typeof(PlaylistType), HttpUtility.UrlDecode(type));
            }

            List<Playlist> playlists = Playlist.Search(name, parsedType);
            SyndicationFeed feed = new SyndicationFeed();

            string feedTitle = "Playlist search results";
            string feedDescription = "Search results for playlists in the Windows Media Player library";

            if (name == null)
            {
                feedTitle = "All Playlists";
                feedDescription = "All playlists in the Windows Media Player library";
            }

            feed.Title = new TextSyndicationContent(feedTitle);
            feed.Description = new TextSyndicationContent(feedDescription);
            feed.Links.Add(SyndicationLink.CreateAlternateLink(new Uri("http://code.google.com/p/mediafeeder/wiki/Playlists")));
            feed.Generator = XmlString.Generator;
            feed.AttributeExtensions.Add(new XmlQualifiedName(XmlString.ITunesLocalName, XmlString.GenericNameSpace), XmlString.ITunesNamespace);
            feed.AttributeExtensions.Add(new XmlQualifiedName(XmlString.MediaFeederLocalName, XmlString.GenericNameSpace), XmlString.MediaFeederNamespace);
            List<SyndicationItem> items = new List<SyndicationItem>();

            foreach (Playlist playlist in playlists)
            {
                PlaylistSyndicationItem item = new PlaylistSyndicationItem(playlist);
                items.Add(item);
            }

            feed.Items = items;
            return Utility.GetFormatter(feed);
        }

        /// <summary>
        /// Plays the playlist in Media Center.
        /// </summary>
        public void PlayPlaylist(string name)
        {
            string decodedName = HttpUtility.UrlDecode(name);

            if (!Playlist.Exists(decodedName))
            {
                WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.NotFound;
            }

            Playlist playlist = new Playlist(decodedName);
            playlist.Play();
        }
    }
}
